from django.shortcuts import render
from rest_framework.response import Response
from rest_framework.viewsets import ViewSet
from rest_framework import status
from django_redis import get_redis_connection
from rest_framework.permissions import IsAuthenticated

from courses.models import CourseExpire, Course


class CartAPIViewSet(ViewSet):
    permission_classes = [IsAuthenticated]

    def add_cart(self, request):
        """添加商品到购物车"""
        user_id = request.user.id  # 获取用户ID

        course_id = request.data.get("course_id")  # 商品ID

        expire = 0  # 0表示没有没有勾选,默认是有效期

        try:
            # 验证课程是否存在
            Course.objects.get(pk=course_id, is_show=True, is_delete=False)
        except Course.DoesNotExist:
            return Response({"message": "对不起，添加商品不存在"}, status=status.HTTP_400_BAD_REQUEST)
            # todo 判断用户是否已经购买了商品，如果已经购买不在有效期内，则不能添加到购物车

        # 链接redis
        redis_conn = get_redis_connection("cart")

        # 保存数据到redis
        # 把商品ID和商品有效期存放在hash中
        pipe = redis_conn.pipeline()
        pipe.multi()

        pipe.hset("cart_%s" % user_id, course_id, expire)
        pipe.sadd("selected_%s" % user_id, course_id)  # 默认勾选状态

        pipe.execute()
        cart_length = redis_conn.hlen("cart_%s" % user_id)

        # 返回响应结果
        return Response({"message": "成功添加商品到购物车", "cart_length": cart_length})

    def get_cart(self, request):
        """获取购物车中的商品信息"""
        # 获取用户id
        user_id = request.user.id
        # 连接redis
        redis_conn = get_redis_connection("cart")
        cart_hash = redis_conn.hgetall("cart_%s" % user_id)
        selected_set = redis_conn.smembers("selected_%s" % user_id)
        # 根据购物车中的商品id到mysql中提取商品具体信息
        data = []
        for course_id_bytes, expire_bytes in cart_hash.items():
            course_id = course_id_bytes.decode()
            expire = int(expire_bytes.decode())
            try:
                course = Course.objects.get(pk=course_id, is_show=True, is_delete=False)
            except Course.DoesNotExist:
                # 如果当前商品被下架或者被逻辑删除了则不显示到购物车商品列表中
                continue

            data.append({
                "course_id": course.id,
                "course_img": course.course_img.url,  # 后面必须加url
                "course_name": course.name,
                "expire_list": course.expire_list,  # todo 后面实现了课程购买有效期以后返回有效期选项列表
                "expire_time": expire,
                # "price": course.get_price_by_expire(expire),  #显示价格
                "price": course.get_discount_price_by_expire(expire),  # 显示价格
                "selected": course_id_bytes in selected_set,
            })
            # 返回结果
        return Response(data)

    def change_selected_staus(self, request):
        """修改商品勾选状态"""

        user_id = request.user.id  # 用户id
        course_id = request.data.get('course_id')  # 商品
        selected = request.data.get('selected')  # 状态

        # 连接redis
        redis_conn = get_redis_connection('cart')

        # 切换勾选状态
        if selected:
            """勾选"""
            redis_conn.sadd('selected_%s' % user_id, course_id)
        else:
            """去掉勾选"""
            redis_conn.srem('selected_%s' % user_id, course_id)

        # 返回结果
        return Response({"message": "切换勾选状成功！"})

    def delete_cart(self, request):
        """删除购物车中的商品"""

        # 接受客户端提交的数据【user_id,course_id】
        user_id = request.user.id  # 用户id
        course_id = request.query_params.get('course_id')

        try:
            Course.objects.get(id=course_id)
        except Course.DoesNotExist:
            return Response({"message": "删除商品数据成功"})

        # 连接redis
        redis_conn = get_redis_connection('cart')

        # 根据用户id删除指定商品id的数据【从hasn和set中删除】
        pipe = redis_conn.pipeline()
        pipe.multi()
        pipe.hdel("cart_%s" % user_id, course_id)
        pipe.srem("selected_%s" % user_id, course_id)
        pipe.execute()

        # 返回结果
        return Response({"message": "删除商品数据成功！！"})

    def change_expire(self, request):
        """切换课程的有效期选项"""
        user_id = request.user.id
        course_id = request.data.get("course_id")
        expire_time = request.data.get("expire")

        # 验证数据

        try:
            Course.objects.get(pk=course_id, is_show=True, is_delete=False)
        except Course.DoesNotExist:
            return Response({"message": "切换有效期的课程不存在！"},
                            status=status.HTTP_400_BAD_REQUEST)
        if expire_time > 0:
            try:
                CourseExpire.objects.get(course_id=course_id, expire=expire_time)
            except CourseExpire.DoesNotExist:
                return Response({"message": "当前课程的有效期选项不存在"},
                                status=status.HTTP_400_BAD_REQUEST)
        # 连接redis
        redis_conn = get_redis_connection('cart')

        # 修改有效期选项
        redis_conn.hset("cart_%s" % user_id, course_id, expire_time)

        # 返回结果
        return Response({"message": "修改有效期选项成功！"})

    def get_select_course(self, request):
        """获取购物车中被勾选的商品信息"""
        user_id = request.user.id  # 获取用户id

        # 根据用户id到购物车中查询商品信息
        redis_conn = get_redis_connection("cart")
        cart_hash = redis_conn.hgetall("cart_%s" % user_id)
        selected_set = redis_conn.smembers("selected_%s" % user_id)

        # 根据购物车中的商品id到mysql中提取商品具体信息

        data = []
        for course_id_bytes in selected_set:
            course_id = course_id_bytes.decode()
            expire = int(cart_hash[course_id_bytes].decode())

            try:
                course = Course.objects.get(pk=course_id, is_show=True, is_delete=False)
            except Course.DoesNotExist:
                # 如果当前商品被下架或者被逻辑删除了则不显示到购物车中商品列表中
                continue
            try:
                ret = CourseExpire.objects.get(course_id=course_id, expire=expire)
                expire_text = ret.text
            except:
                expire_text = '永久有效'
            data.append({
                "course_id": course_id,
                "course_img": course.course_img.url,
                "course_name": course.name,
                "discount_name": course.discount_name,
                "expire_text": expire_text,
                "original_price": course.get_price_by_expire(expire),
                "discount_price": course.get_discount_price_by_expire(expire),
            })
        return Response(data)
